
const path = require('path')
// 引入自动生成 html 的插件
const HtmlWebpackPlugin = require('html-webpack-plugin')
// 引入分离 css 文件的 模块
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
// 使用插件压缩css 代码
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin')
// 使用插件压缩 js 代码 (生产模式)
const TerserPlugin = require('terser-webpack-plugin')

// 底下都是  后缀名不同的一些配置  在plugins 来配置rules
const toml = require('toml')
const yaml = require('yaml')
const json5 = require('json5')

// 配置webpack的配置文件, 需要将配置的对象导出, 给webpack使用
module.exports = (env) => {
  return {
    // 入口 entry, 从哪个文件开始打包
    entry: {
      index: './src/index.js',
      another: './src/another-module.js'
    },
    // 出口 output, 打包到哪里去
    output: {
      // 打包后生成的文件名
      filename: 'scripts/[name].[contenthash].js',
      // 打包输出的目录 (输出的目录必须是一个绝对路径)
      path: path.resolve(__dirname, './dist'),
      // 删除不需要的旧文件
      clean: true,
      // assetModuleFilename和generator  优先级更高的是(generator)
      assetModuleFilename: 'images/[contenthash][ext]',
      // publicPath 配置公共路径，所有文件的引用将自动添加公共路径的绝对地址
      publicPath: 'http://localhost:8080/'
    },

    // mode什么模式
    mode: env.production ? 'production' : 'development',

    // 可以理解成debuger
    devtool: 'inline-source-map',

    plugins: [
      new HtmlWebpackPlugin({
        template: './index.html',
        filename: 'app.html',
        // 指定 Script 标签位置
        inject: 'body'
      }),

      new MiniCssExtractPlugin({
        // [contenthash]系统自定义Name
        filename: 'styles/[contenthash].css'
      })
    ],

    devServer: {
      static: './dist'
    },

    module: {
      rules: [
        {
          test: /\.png$/,
          type: 'asset/resource',
          generator: {
            filename: 'images/[contenthash][ext]'
          }
        },

        {
          test: /\.svg$/,
          type: 'asset/inline'
        },

        {
          test: /\.txt$/,
          type: 'asset/source'
        },

        {
          test: /\.jpg$/,
          type: 'asset',
          parser: {
            dataUrlCondition: {
              maxSize: 4 * 1024 * 1024
            }
          }
        },
        {
          test: /\.s[ac]ss$/i,
          use: [
            // 在 head 中创建 style 标签
            'style-loader',
            // 将 css 文件整合到 js 文件中
            'css-loader',
            // 编译 sass 文件为 css 文件
            'sass-loader'
          ]
        },

        {
          test: /\.(css|less)$/,
          use: [MiniCssExtractPlugin.loader, 'css-loader', 'less-loader']
        },

        {
          test: /\.(woff|woff2|eot|ttf|otf)$/,
          type: 'asset/resource'
        },

        {
          test: /\.(csv|tsv)$/,
          use: 'csv-loader'
        },

        {
          test: /\.xml$/,
          use: 'xml-loader'
        },

        {
          test: /\.toml$/,
          type: 'json',
          parser: {
            parse: toml.parse
          }
        },

        {
          test: /\.yaml$/,
          type: 'json',
          parser: {
            parse: yaml.parse
          }
        },

        {
          test: /\.json5$/,
          type: 'json',
          parser: {
            parse: json5.parse
          }
        },

        {
          test: /\.js$/,
          exclude: /node_modules/,
          use: {
            loader: 'babel-loader',
            options: {
              presets: ['@babel/preset-env'],
              plugins: [
                [
                  '@babel/plugin-transform-runtime'
                ]
              ]
            }
          }
        }
      ]
    },

    optimization: {
      minimizer: [
        // 使用插件压缩css 代码
        new CssMinimizerPlugin(),
        // 使用插件压缩 js 代码 (生产模式)
        new TerserPlugin()
      ],

      // 缓存第三方库 比如 JQuery
      splitChunks: {
        cacheGroups: {
          vendor: {
            test: /[\\/]node_modules[\\/]/,
            name: 'vendors',  //取的别名
            chunks: 'all'
          }
        }
      }
    }
  }
}